/**
 * Office 文档在线预览工具类
 * 支持多种在线预览服务，包括Microsoft Office Online、Google Docs等
 * 
 * 使用示例：
 * ```typescript
 * // 创建预览器实例
 * const viewer = new OfficeViewer({ service: 'microsoft' })
 * 
 * // 生成预览URL
 * const viewerUrl = viewer.generateViewerUrl('https://example.com/document.pdf')
 * 
 * // 验证文件
 * const validation = FileUploader.validateFile(file)
 * ```
 */

/**
 * 预览服务配置接口
 * @property service - 预览服务类型：'microsoft' | 'google' | 'custom'
 * @property baseUrl - 自定义预览服务的基础URL（仅当service为'custom'时需要）
 * @property width - 预览窗口宽度，默认'100%'
 * @property height - 预览窗口高度，默认'600px'
 */
export interface ViewerConfig {
  service: 'microsoft' | 'google' | 'custom'
  baseUrl?: string
  width?: string
  height?: string
}

/**
 * 文件信息接口
 * @property name - 文件名
 * @property type - 文件类型（扩展名）
 * @property url - 文件URL
 * @property size - 文件大小（字节）
 */
export interface FileInfo {
  name: string
  type: string
  url: string
  size?: number
}

/**
 * Office文档预览器主类
 * 负责生成不同预览服务的URL，管理预览配置
 */
export class OfficeViewer {
    private config: ViewerConfig;

    /**
     * 构造函数
     * @param config - 预览器配置，默认使用Microsoft服务
     * 
     * 使用示例：
     * ```typescript
     * // 使用默认配置（Microsoft服务）
     * const viewer = new OfficeViewer()
     * 
     * // 使用Google服务
     * const viewer = new OfficeViewer({ service: 'google' })
     * 
     * // 使用自定义服务
     * const viewer = new OfficeViewer({ 
     *   service: 'custom', 
     *   baseUrl: 'https://my-viewer.com/view' 
     * })
     * ```
     */
    constructor(config: ViewerConfig = { service: 'microsoft' }) {
        this.config = {
            width: '100%',
            height: '600px',
            ...config
        };
    }

    /**
     * 生成文档预览URL
     * 根据配置的预览服务，生成对应的预览URL
     * 
     * @param fileUrl - 要预览的文件URL（必须是公开可访问的）
     * @returns 预览服务的完整URL
     * 
     * 使用示例：
     * ```typescript
     * const viewer = new OfficeViewer()
     * const previewUrl = viewer.generateViewerUrl('https://example.com/document.pdf')
     * // 返回: https://view.officeapps.live.com/op/embed.aspx?src=https%3A//example.com/document.pdf
     * ```
     */
    generateViewerUrl(fileUrl: string): string {
        const encodedUrl = encodeURIComponent(fileUrl);
    
        switch (this.config.service) {
        case 'microsoft':
            return this.generateMicrosoftUrl(encodedUrl);
        case 'google':
            return this.generateGoogleUrl(encodedUrl);
        case 'custom':
            return this.generateCustomUrl(encodedUrl);
        default:
            return this.generateMicrosoftUrl(encodedUrl);
        }
    }

    /**
     * 生成Microsoft Office Online Viewer URL
     * Microsoft官方提供的Office文档在线预览服务
     * 支持格式最全面，包括Word、Excel、PowerPoint、PDF等
     * 
     * @param encodedUrl - 编码后的文件URL
     * @returns Microsoft预览服务URL
     */
    private generateMicrosoftUrl(encodedUrl: string): string {
        return `https://view.officeapps.live.com/op/embed.aspx?src=${encodedUrl}`;
    }

    /**
     * 生成Google Docs Viewer URL
     * Google提供的文档预览服务
     * 加载速度较快，但支持格式相对较少
     * 
     * @param encodedUrl - 编码后的文件URL
     * @returns Google预览服务URL
     */
    private generateGoogleUrl(encodedUrl: string): string {
        return `https://docs.google.com/viewer?url=${encodedUrl}&embedded=true`;
    }

    /**
     * 生成自定义预览服务URL
     * 用于集成自己的文档预览服务
     * 
     * @param encodedUrl - 编码后的文件URL
     * @returns 自定义预览服务URL
     * @throws Error 如果未提供baseUrl配置
     */
    private generateCustomUrl(encodedUrl: string): string {
        if (!this.config.baseUrl) {
            throw new Error('自定义预览服务需要提供baseUrl配置');
        }
        return `${this.config.baseUrl}?url=${encodedUrl}`;
    }

    /**
     * 检查文件类型是否支持预览
     * 静态方法，无需创建实例即可使用
     * 
     * @param fileName - 文件名（包含扩展名）
     * @returns 是否支持预览
     * 
     * 使用示例：
     * ```typescript
     * const isSupported = OfficeViewer.isSupportedFileType('document.pdf')
     * // 返回: true
     * 
     * const isSupported = OfficeViewer.isSupportedFileType('image.jpg')
     * // 返回: false
     * ```
     */
    static isSupportedFileType(fileName: string): boolean {
        const supportedExtensions = [
            'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf',
            'txt', 'rtf', 'odt', 'ods', 'odp'
        ];
        const extension = fileName.split('.').pop()?.toLowerCase();
        return supportedExtensions.includes(extension || '');
    }

    /**
     * 获取文件类型信息
     * 返回文件类型的显示名称、颜色和图标信息
     * 静态方法，无需创建实例即可使用
     * 
     * @param fileName - 文件名（包含扩展名）
     * @returns 文件类型信息对象
     * 
     * 使用示例：
     * ```typescript
     * const fileInfo = OfficeViewer.getFileTypeInfo('document.docx')
     * // 返回: { name: 'Word文档', color: 'primary', icon: 'Document' }
     * ```
     */
    static getFileTypeInfo(fileName: string) {
        const extension = fileName.split('.').pop()?.toLowerCase();
    
        const typeMap = {
            'doc': { name: 'Word文档', color: 'primary', icon: 'Document' },
            'docx': { name: 'Word文档', color: 'primary', icon: 'Document' },
            'xls': { name: 'Excel表格', color: 'success', icon: 'Grid' },
            'xlsx': { name: 'Excel表格', color: 'success', icon: 'Grid' },
            'ppt': { name: 'PowerPoint演示', color: 'warning', icon: 'VideoPlay' },
            'pptx': { name: 'PowerPoint演示', color: 'warning', icon: 'VideoPlay' },
            'pdf': { name: 'PDF文档', color: 'danger', icon: 'Document' },
            'txt': { name: '文本文件', color: 'info', icon: 'Document' },
            'rtf': { name: '富文本文件', color: 'info', icon: 'Document' },
            'odt': { name: 'OpenDocument文本', color: 'primary', icon: 'Document' },
            'ods': { name: 'OpenDocument表格', color: 'success', icon: 'Grid' },
            'odp': { name: 'OpenDocument演示', color: 'warning', icon: 'VideoPlay' }
        };

        return typeMap[extension as keyof typeof typeMap] || {
            name: '未知类型',
            color: 'info',
            icon: 'Document'
        };
    }

    /**
     * 创建预览iframe元素
     * 动态创建用于嵌入预览的iframe元素
     * 
     * @param url - 预览URL
     * @param options - iframe配置选项
     * @param options.width - iframe宽度，默认使用配置中的宽度
     * @param options.height - iframe高度，默认使用配置中的高度
     * @param options.allowFullscreen - 是否允许全屏，默认true
     * @returns 配置好的iframe元素
     * 
     * 使用示例：
     * ```typescript
     * const viewer = new OfficeViewer()
     * const iframe = viewer.createViewerIframe(previewUrl, {
     *   width: '800px',
     *   height: '600px',
     *   allowFullscreen: true
     * })
     * document.body.appendChild(iframe)
     * ```
     */
    createViewerIframe(url: string, options: {
    width?: string
    height?: string
    allowFullscreen?: boolean
  } = {}): HTMLIFrameElement {
        const iframe = document.createElement('iframe');
        iframe.src = url;
        iframe.width = options.width || this.config.width || '100%';
        iframe.height = options.height || this.config.height || '600px';
        iframe.frameBorder = '0';
        iframe.allowFullscreen = options.allowFullscreen !== false;
    
        return iframe;
    }

    /**
     * 更新预览服务配置
     * 动态修改预览器的配置
     * 
     * @param newConfig - 新的配置参数
     * 
     * 使用示例：
     * ```typescript
     * const viewer = new OfficeViewer({ service: 'microsoft' })
     * 
     * // 切换到Google服务
     * viewer.updateConfig({ service: 'google' })
     * 
     * // 修改预览窗口大小
     * viewer.updateConfig({ width: '800px', height: '500px' })
     * ```
     */
    updateConfig(newConfig: Partial<ViewerConfig>) {
        this.config = { ...this.config, ...newConfig };
    }

    /**
     * 获取可用的预览服务选项
     * 静态方法，返回所有支持的预览服务信息
     * 
     * @returns 预览服务选项数组
     * 
     * 使用示例：
     * ```typescript
     * const services = OfficeViewer.getViewerServices()
     * // 返回: [
     * //   { value: 'microsoft', label: 'Microsoft Office Online', description: '...' },
     * //   { value: 'google', label: 'Google Docs Viewer', description: '...' },
     * //   { value: 'custom', label: '自定义服务', description: '...' }
     * // ]
     * ```
     */
    static getViewerServices() {
        return [
            {
                value: 'microsoft',
                label: 'Microsoft Office Online',
                description: '微软官方Office在线预览服务，支持格式最全面'
            },
            {
                value: 'google',
                label: 'Google Docs Viewer',
                description: 'Google文档预览服务，加载速度较快'
            },
            {
                value: 'custom',
                label: '自定义服务',
                description: '使用自定义的文档预览服务'
            }
        ];
    }
}

/**
 * 文件上传工具类
 * 提供文件验证、URL创建等辅助功能
 */
export class FileUploader {
    /**
     * 验证文件是否支持预览
     * 检查文件大小和格式是否符合要求
     * 
     * @param file - 要验证的文件对象
     * @returns 验证结果对象
     * @returns validation.valid - 是否验证通过
     * @returns validation.message - 错误信息（验证失败时）
     * 
     * 使用示例：
     * ```typescript
     * const file = event.target.files[0]
     * const validation = FileUploader.validateFile(file)
     * 
     * if (validation.valid) {
     *   console.log('文件验证通过')
     * } else {
     *   console.error('文件验证失败:', validation.message)
     * }
     * ```
     */
    static validateFile(file: File): { valid: boolean; message?: string } {
        const maxSize = 50 * 1024 * 1024; // 50MB
        const supportedTypes = [
            'application/msword',
            'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
            'application/vnd.ms-excel',
            'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            'application/vnd.ms-powerpoint',
            'application/vnd.openxmlformats-officedocument.presentationml.presentation',
            'application/pdf',
            'text/plain',
            'application/rtf'
        ];

        if (file.size > maxSize) {
            return { valid: false, message: '文件大小不能超过50MB' };
        }

        if (!supportedTypes.includes(file.type) && !OfficeViewer.isSupportedFileType(file.name)) {
            return { valid: false, message: '不支持的文件格式' };
        }

        return { valid: true };
    }

    /**
     * 创建文件对象URL
     * 为本地文件创建可用于预览的URL
     * 
     * @param file - 文件对象
     * @returns 文件对象URL
     * 
     * 使用示例：
     * ```typescript
     * const file = event.target.files[0]
     * const objectUrl = FileUploader.createObjectURL(file)
     * 
     * // 使用完毕后记得释放
     * FileUploader.revokeObjectURL(objectUrl)
     * ```
     */
    static createObjectURL(file: File): string {
        return URL.createObjectURL(file);
    }

    /**
     * 释放文件对象URL
     * 释放通过createObjectURL创建的URL，避免内存泄漏
     * 
     * @param url - 要释放的文件对象URL
     * 
     * 使用示例：
     * ```typescript
     * const objectUrl = FileUploader.createObjectURL(file)
     * 
     * // 使用完毕后释放
     * FileUploader.revokeObjectURL(objectUrl)
     * ```
     */
    static revokeObjectURL(url: string): void {
        URL.revokeObjectURL(url);
    }
}

// 默认导出OfficeViewer类
export default OfficeViewer; 